package cn.tlb.gl.texture_2d;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLUtils;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import cn.tlb.xutilsdownload.R;

/**
 * Created by 汤林冰 on 2015/12/9 17:18.
 */
public class Renderer_2D implements Renderer {

    //正方形贴图
    float[] vertices = {
         0.5f,  0.5f, 0,
        -0.5f,  0.5f, 0,
         0.5f, -0.5f, 0,

        -0.5f, -0.5f, 0,
        -0.5f,  0.5f, 0,
         0.5f, -0.5f, 0

    };

    byte[] indices = {
        0,1,2,
        3,4,5
    };

    float[] texture = {
        1, 0,
        0, 0,
        1, 1,

        0, 1,
        0, 0,
        1, 1
    };

    Context context;
    FloatBuffer verticesBuffer;
    FloatBuffer textureBuffer;
    ByteBuffer indicesByteBuffer;
    int textureId = 0;

    public Renderer_2D(Context context) {
        this.context = context;
        verticesBuffer = array2FloatBuffer(vertices);
        textureBuffer = array2FloatBuffer(texture);
        indicesByteBuffer = ByteBuffer.wrap(indices);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glDisable(GL10.GL_DITHER);
        gl.glShadeModel(GL10.GL_SMOOTH);

        gl.glClearColor(0, 0, 0, 0);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);

        //启用2d纹理贴图
        gl.glEnable(GL10.GL_TEXTURE_2D);
        loadTexture(gl);
    }

    private void loadTexture(GL10 gl) {
        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.skycubemap1);

        int[] textures = new int[1];
        gl.glGenTextures(1,textures, 0);
        textureId = textures[0];
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

        bitmap.recycle();
        bitmap = null;
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        float ratio = (float)width/height;
        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT|GL10.GL_COLOR_BUFFER_BIT);
        gl.glMatrixMode(GL10.GL_MODELVIEW);

        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        gl.glLoadIdentity();

        gl.glTranslatef(0,0,-2);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, verticesBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId);

        gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, indicesByteBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indicesByteBuffer);

        gl.glFinish();
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    }

    private FloatBuffer array2FloatBuffer(float fs[]){
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(fs.length * 4);
        byteBuffer.order(ByteOrder.nativeOrder());
        FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
        floatBuffer.put(fs);
        floatBuffer.position(0);
        return floatBuffer;
    }

    private IntBuffer array2IntBuffer(int ints[]){
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(ints.length*4);
        byteBuffer.order(ByteOrder.nativeOrder());
        IntBuffer intBuffer = byteBuffer.asIntBuffer();
        intBuffer.put(ints);
        intBuffer.position(0);
        return intBuffer;
    }
}
